package com.soccertgc.core.game.requests
{

	import com.soccertgc.comm.Call;
	import com.soccertgc.core.game.GamePhase;
	import com.soccertgc.core.game.GameServerStatus;
	import com.soccertgc.logging.Logger;

	/**
	 * Abstract class for game phase 
	 * @author ltavecchia
	 */	
	public class GameRequest
	{
		
		// -------------------------------------------------------------------------------
		// CONSTANTS
		// -------------------------------------------------------------------------------
		
		// -------------------------------------------------------------------------------
		// FIELDS
		// -------------------------------------------------------------------------------
		
		private var _id:String;
		private var _url:String;
		private var _phase:GamePhase;
		private var _params:GameRequestParams;
		private var _result:GameRequestResult;
		private var _retries:uint;
		
		// -------------------------------------------------------------------------------
		// CONSTRUCTOR
		// -------------------------------------------------------------------------------
		
		/**
		 * Creates a new generic action
		 * @param actionType Type of the action
		 * @param actionId Unique id of the action
		 */		
		public function GameRequest(phase:GamePhase, url:String, id:String)
		{
			// Init
			_phase 			= phase;
			_url			= url;
			_id 			= id;
			_retries		= 0;
		}
		
		// -------------------------------------------------------------------------------
		// PROPERTIES
		// -------------------------------------------------------------------------------

		public function get id():String
		{
			return _id;
		}
		
		public function get phase():GamePhase
		{
			return _phase;
		}
		
		public function get params():GameRequestParams
		{
			return _params;
		}
		
		public function set params(value:GameRequestParams):void
		{
			_params = value;
		}
		
		public function get retries():uint
		{
			return _retries;
		}
		
		public function get result():GameRequestResult
		{
			return _result;
		}
		
		public function get executed():Boolean
		{
			return _result != null;
		}
		
		public function get succeeded():Boolean
		{
			return _result != null && _result.succeeded;
		}
		
		public function get waiting():Boolean
		{
			return _result != null && _result.waiting;
		}
		
		public function get isInError():Boolean
		{
			return _result != null && _result.isInError;
		}
		
		public function get isRequest():Boolean
		{
			return !_phase.polling;
		}
		
		public function get isPollingRequest():Boolean
		{
			return _phase.polling;
		}		
		
		// -------------------------------------------------------------------------------
		// PRIVATE METHODS
		// -------------------------------------------------------------------------------

		/**
		 * Virtual method to override in descendant classes to update the status of the 
		 * action after the execution (currently not used)
		 */		
		protected function setup(params:GameRequestParams):void
		{
			// LT_TODO: Logger.warn("GameRequest.setup() MUST be implemented in the class descendants");
		}
		
		/**
		 * Virtual method to override in descendant classes to update the status of the 
		 * action after the execution (currently not used)
		 */		
		protected function update(result:GameRequestResult):void
		{
			// LT_TODO: Logger.warn("GameRequest.update() MUST be implemented in the class descendants");
		}
		
		
		// -------------------------------------------------------------------------------
		// PUBLIC METHODS
		// -------------------------------------------------------------------------------
		
		/**
		 * Initializes the request with all the parameters required to
		 * @param params Parameters to attach to the request
		 */		
		public function init(params:GameRequestParams):void
		{
			// Setup to validate params for the request
			setup(params);
			// Save the param reference
			_params = params;
		}
		
		/**
		 * Process the results data obtained with the request to the server
		 * @param result Results object to process
		 */		
		public function process(result:GameRequestResult):void
		{
			// If the action succeeded, update action status
			if (result.succeeded)
			{
				update(result);
			}
			// Save the result
			_result = result;
		}
		
		/**
		 * Creates the Call used to make the request to the server
		 * @return Call object that represents the request
		 */		
		public function createCall():Call
		{
			// Check params
			if (_params == null) throw new Error(toString() + " parameters should not be null or empty!");
			// Creates the call
			var call:Call = new Call(_url, true);
			call.params = _params.createCallParams();
			return call;
		}
		
		/**
		 * 
		 * @param action
		 * @return  
		 */		
		public function equals(action:GameRequest):Boolean
		{
			return	_id		== action.id		&&
					_phase	== action.phase;
		}
		
		/**
		 * Handles the request retry, cancels the current result and increment the retry counter 
		 */		
		public function retry():void
		{
			_retries++;
			_result = null;
		}
		
		
		/**
		 * 
		 * @return 
		 * 
		 */		
		public function toString():String
		{
			return "GameRequest::" + _phase.name + " (id: " +_id  + ")"; // LT_TODO: aggiungere altre informazioni
		}
		
	}
}